﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.OracleClient;
using System.IO;
using System.Diagnostics;
using System.Net;

namespace WinFormsApp_CheckPortUsable
{
    public partial class TestConnectionAndCheckPortForm : Form
    {
        public TestConnectionAndCheckPortForm()
        {
            InitializeComponent();
        }
        private string FilePath = Application.StartupPath + "\\";

        /// <summary>
        /// 生成错误日志
        /// </summary>
        /// <param name="FilePath">文件路径</param>
        /// <param name="message">错误消息</param>
        private void SaveError(string FilePath, string message)
        {
            string splitLine = "--------------------------------";
            if (!File.Exists(FilePath))//日志文件存在
            {
                FileStream fs = File.Create(FilePath);
                fs.Close();
            }
            StreamReader reader = new StreamReader(FilePath);//读取日志文件
            string msg = reader.ReadToEnd() + splitLine + DateTime.Now.ToString() + splitLine + "\r\n" + message;
            reader.Close();
            StreamWriter sw = new StreamWriter(FilePath);//将错误信息追加到文件中
            sw.WriteLine(msg);
            sw.Close();
        }

        /// <summary>
        /// 切换面板
        /// </summary> 
        private void tbcDB_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.tbcDB.SelectedTab.Name == "tbpPort")
            {
                this.btnTest.Enabled = false;
                this.pnlPort.Visible = true;
                this.btnTestUDP.Visible = true;
            }
            else if (this.tbcDB.SelectedTab.Name == "tabPort2")
            {
                this.btnTest.Enabled = false;
                this.pnlPort.Visible = true;
                this.btnTestUDP.Visible = false;
            }
            else
            {
                this.btnTest.Enabled = true;
                this.pnlPort.Visible = false;
            }
        }

        /// <summary>
        /// 退出按钮
        /// </summary> 
        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        //测试连接按钮
        private void btnTest_Click(object sender, EventArgs e)
        {
            if (this.tbcDB.SelectedTab.Name == "tbpSqlserver")//SQL SERVER连接
            {
                string server = this.txtDBServer.Text.Trim();
                string dbname = this.txtDBName.Text.Trim();
                string dbloginname = this.txtDBLoginName.Text.Trim();
                string dbloginpwd = this.txtDBPassword.Text.Trim();
                string sql = string.Format("server={0};database={1};uid={2};pwd={3};", server, dbname, dbloginname, dbloginpwd);
                SqlConnection conn = new SqlConnection(sql);
                try
                {
                    conn.Open();
                    MessageBox.Show("SQL SERVER连接成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
                catch (Exception ex)
                {
                    SaveError(FilePath + "SqlserverError.log", ex.Message);
                    MessageBox.Show("SQL SERVER连接失败！" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
            }
            else if (this.tbcDB.SelectedTab.Name == "tbpOracle")//Oracle连接
            {
                string datasource = this.txtODBName.Text.Trim();
                string loginname = this.txtODBUserName.Text.Trim();
                string loginpwd = this.txtODBPassword.Text.Trim();
                string sql = string.Format("data source={0};user id={1};password={2};", datasource, loginname, loginpwd);
                OracleConnection conn = new OracleConnection(sql);
                try
                {
                    conn.Open();
                    MessageBox.Show("Oracle连接成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
                catch (Exception ex)
                {
                    SaveError(FilePath + "OracleError.log", ex.Message);
                    MessageBox.Show("Oracle连接失败！" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
            }
        }

        #region 检测端口号

        /// <summary>
        /// 检测TCP或UDP端口是否可用
        /// </summary> 
        public bool CheckPort(string tempPort)
        {
            Process p = new Process();
            p.StartInfo = new ProcessStartInfo("netstat", "-an");
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.StartInfo.RedirectStandardOutput = true;
            p.Start();
            string result = p.StandardOutput.ReadToEnd().ToLower();//最后都转换成小写字母
            System.Net.IPAddress[] addressList = Dns.GetHostByName(Dns.GetHostName()).AddressList;
            List<string> ipList = new List<string>();
            ipList.Add("127.0.0.1");
            ipList.Add("0.0.0.0");
            for (int i = 0; i < addressList.Length; i++)
            {
                ipList.Add(addressList[i].ToString());
            }
            bool use = false;
            for (int i = 0; i < ipList.Count; i++)
            {
                if (result.IndexOf("tcp    " + ipList[i] + ":" + tempPort) >= 0 || result.IndexOf("udp    " + ipList[i] + ":" + tempPort) >= 0)
                {
                    use = true;
                    break;
                }
            }
            p.Close();
            return use;
        }

        //检测TCP端口
        private void btnTestTCP_Click(object sender, EventArgs e)
        {
            if (this.tbcDB.SelectedTab.Name == "tabPort2")
            {
                string tcpPort2 = this.txtPort2.Text.Trim();
                if (tcpPort2 == "" || tcpPort2 == null)
                {
                    this.lblMessage.Text = "";
                    MessageBox.Show("请输入TCP端口号！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
                else
                {
                    bool isUse = CheckPort(tcpPort2.Trim());
                    if (isUse)
                    {
                        MessageBox.Show("端口号已被占用！");
                    }
                    else
                    {
                        MessageBox.Show("端口号可以使用！");
                    }
                }
            }
            else
            {
                string tcpPort = this.txtTCP.Text.Trim();
                try
                {
                    if (tcpPort == "" || tcpPort == null)
                    {
                        this.lblMessage.Text = "";
                        MessageBox.Show("请输入TCP端口号！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                    }
                    else
                    {
                        Process process = new Process();
                        process.StartInfo = new ProcessStartInfo("netstat", "/ano");
                        process.StartInfo.CreateNoWindow = true;
                        process.StartInfo.UseShellExecute = false;
                        process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                        process.StartInfo.RedirectStandardOutput = true;
                        process.Start();
                        StreamReader reader = process.StandardOutput;
                        while (!reader.EndOfStream)
                        {
                            string msg = reader.ReadLine().ToUpper();
                            if (msg.IndexOf("TCP") > 0 && msg.IndexOf(":" + tcpPort) > 0)
                            {
                                string info = msg.Trim();
                                this.lblMessage.Text = "TCP进程的PID为：" + info.Substring(info.Length - 5, 5);
                                MessageBox.Show("TCP：" + tcpPort + "端口被占用！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                                break;
                            }
                            else
                            {
                                this.lblMessage.Text = "";
                            }
                        }
                        reader.Close();
                        process.Close();
                    }
                }
                catch (Exception ex)
                {
                    SaveError(FilePath + "TCPError.log", "检测TCP端口：" + tcpPort + "失败！" + ex.Message);
                    MessageBox.Show("检测TCP端口：" + tcpPort + "失败！" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
            }
        }
        //检测UDP端口
        private void btnTestUDP_Click(object sender, EventArgs e)
        {
            string udpPort = this.txtUDP.Text.Trim();
            try
            {
                if (udpPort == "" || udpPort == null)
                {
                    this.lblMessage.Text = "";
                    MessageBox.Show("请输入UDP端口号！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
                else
                {
                    Process process = new Process();
                    process.StartInfo = new ProcessStartInfo("netstat", "/ano");
                    process.StartInfo.CreateNoWindow = true;
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    process.StartInfo.RedirectStandardOutput = true;
                    process.Start();
                    StreamReader reader = process.StandardOutput;
                    while (!reader.EndOfStream)
                    {
                        string msg = reader.ReadLine().ToUpper();
                        if (msg.IndexOf("UDP") > 0 && msg.IndexOf(":" + udpPort) > 0)
                        {
                            string info = msg.Trim();
                            this.lblMessage.Text = "UDP进程的PID为：" + info.Substring(info.Length - 5, 5);
                            MessageBox.Show("UDP：" + udpPort + "端口被占用！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                            break;
                        }
                        else
                        {
                            this.lblMessage.Text = "";
                        }
                    }
                    reader.Close();
                    process.Close();
                }
            }
            catch (Exception ex)
            {
                SaveError(FilePath + "UDPError.log", "检测UDP端口：" + udpPort + "失败！" + ex.Message);
                MessageBox.Show("检测UDP端口：" + udpPort + "失败！" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
        }

        #endregion
    }
}
